home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
muds
/
pennmush.000
/
pennmush-1.50-p8-linux.tar
/
pennmush
/
create.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-17
|
14KB
|
549 lines
/* create.c */
/* Commands that create new objects */
#include <string.h>
#include "config.h"
#include "db.h"
#include "attrib.h"
#include "interface.h"
#include "externs.h"
/* utility for open and link */
static dbref parse_linkable_room(player, room_name)
dbref player;
const char *room_name;
{
dbref room;
/* skip leading NUMBER_TOKEN if any */
if (*room_name == NUMBER_TOKEN)
room_name++;
/* parse room */
if (!strcasecmp(room_name, "here")) {
room = Location(player);
} else if (!strcasecmp(room_name, "home")) {
return HOME; /* HOME is always linkable */
} else {
room = parse_dbref(room_name);
}
/* check room */
if (!GoodObject(room)) {
notify(player, "That is not a valid object.");
return NOTHING;
} else if (Going(room)) {
notify(player, "That room is being destroyed. Sorry.");
return NOTHING;
} else if (!can_link_to(player, room)) {
notify(player, "You can't link to that.");
return NOTHING;
} else {
return room;
}
}
int do_real_open(player, direction, linkto, pseudo)
dbref player;
const char *direction;
const char *linkto;
dbref pseudo; /* a phony location for a player if a back
* exit is needed */
{
/* function creates an exit. Note that it returns 0 and NOT -1
* if it fails.
*/
dbref loc = (pseudo != NOTHING) ? pseudo : Location(player);
dbref new_exit;
if ((loc == NOTHING) || (Typeof(loc) != TYPE_ROOM)) {
notify(player, "Sorry you can only make exits out of rooms.");
return 0;
}
#ifdef RESTRICTED_BUILDING
if (!Builder(player)) {
notify(player, "That command is restricted to authorized builders.");
return 0;
}
#endif /* RESTRICTED_BUILDING */
#ifdef GUEST_RESTRICT
if (Guest(player)) {
notify(player, "Guests are not allowed to build.");
return 0;
}
#endif
if(!*direction) {
notify(player, "Open where?");
return 0;
} else if (!ok_name(direction)) {
notify(player, "That's a strange name for an exit!");
return 0;
}
if (!controls(player, loc)) {
notify(player, "Permission denied.");
} else if (can_pay_fees(player, EXIT_COST)) {
/* create the exit */
new_exit = new_object();
/* initialize everything */
SET(db[new_exit].name, direction);
Owner(new_exit) = Owner(player);
Zone(new_exit) = Zone(player);
Exits(new_exit) = loc;
Flags(new_exit) = TYPE_EXIT;
Flags(new_exit) |= options.exit_flags;
Toggles(new_exit) |= options.exit_toggles;
/* link it in */
PUSH(new_exit, Exits(loc));
/* and we're done */
notify(player, "Opened.");
/* check second arg to see if we should do a link */
if (linkto && *linkto != '\0') {
notify(player, "Trying to link...");
if ((loc = parse_linkable_room(player, linkto)) != NOTHING) {
if (!payfor(player, LINK_COST)) {
notify(player, tprintf("You don't have enough %s to link.", MONIES));
} else {
/* it's ok, link it */
Location(new_exit) = loc;
notify(player, "Linked.");
}
}
}
return new_exit;
}
return 0;
}
void do_open(player,direction,links)
dbref player;
const char *direction;
const char *links[];
{
do_real_open(player, direction, links[1], NOTHING);
if(links[2]) {
do_real_open(player, links[2], tprintf("%d",Location(player)),
parse_linkable_room(player, links[1]));
}
}
void do_unlink(player, name)
dbref player;
const char *name;
{
dbref exit_l;
init_match(player, name, TYPE_EXIT);
match_exit();
match_here();
if (Wizard(player)) {
match_absolute();
} else {
match_controlled_absolute();
}
switch (exit_l = match_result()) {
case NOTHING:
notify(player, "Unlink what?");
break;
case AMBIGUOUS:
notify(player, "I don't know which one you mean!");
break;
default:
if (!controls(player, exit_l)) {
notify(player, "Permission denied.");
} else {
switch (Typeof(exit_l)) {
case TYPE_EXIT:
db[exit_l].location = NOTHING;
notify(player, "Unlinked.");
break;
case TYPE_ROOM:
db[exit_l].location = NOTHING;
notify(player, "Dropto removed.");
break;
default:
notify(player, "You can't unlink that!");
break;
}
}
}
}
void do_link(player, name, room_name)
dbref player;
const char *name;
const char *room_name;
{
/* Use this to link to a room that you own.
* It seizes ownership of the exit and costs 1 penny,
* plus a penny transferred to the exit owner if they aren't you.
* You must own the linked-to room AND specify it by room number.
*/
dbref thing;
dbref room;
if (!room_name || !*room_name) {
do_unlink(player, name);
return;
}
if (Typeof(Location(player)) == TYPE_EXIT) {
notify(player, "You somehow wound up in a exit. No biscuit.");
return;
}
init_match(player, name, TYPE_EXIT);
match_everything();
if ((thing = noisy_match_result()) != NOTHING) {
switch (Typeof(thing)) {
case TYPE_EXIT:
if((room = parse_linkable_room(player, room_name)) == NOTHING)
return;
if ((room != HOME) &&
!controls(player, room) && !LinkOk(room)) {
notify(player, "Permission denied.");
break;
}
/* we're ok, check the usual stuff */
if (Location(thing) != NOTHING) {
if (controls(player, thing)) {
if (Typeof(Location(thing)) == TYPE_PLAYER) {
notify(player, "That exit is being carried.");
} else {
notify(player, "That exit is already linked.");
}
} else {
notify(player, "Permission denied.");
}
} else {
/* handle costs */
if (db[thing].owner == Owner(player)) {
if (!payfor(player, LINK_COST)) {
notify(player, tprintf("It costs %d %s to link this exit.",
LINK_COST,
((LINK_COST == 1) ? MONEY : MONIES)));
return;
}
} else {
if (!payfor(player, LINK_COST + EXIT_COST)) {
int a = 0;
notify(player, tprintf("It costs %d %s to link this exit.",
(a = LINK_COST+EXIT_COST),
((a == 1) ? MONEY : MONIES)));
return;
#ifdef RESTRICTED_BUILDING
} else if (!Builder(player)) {
notify(player, "Only authorized builders may seize exits.");
return;
#endif /* RESTRICTED_BUILDING */
#ifdef GUEST_RESTRICT
} else if (Guest(player)) {
notify(player, "Guests are not allowed to build.");
return;
#endif /* GUEST_RESTRICT */
} else {
/* pay the owner for his loss */
giveto(db[thing].owner, EXIT_COST);
}
}
/* link has been validated and paid for; do it */
db[thing].owner = Owner(player);
db[thing].zone = db[player].zone;
Location(thing) = room;
/* notify the player */
notify(player, "Linked.");
}
break;
case TYPE_PLAYER:
case TYPE_THING:
init_match(player, room_name, NOTYPE);
match_everything();
if ((room = noisy_match_result()) < 0) {
notify(player, "No match.");
return;
}
if (Typeof(room) == TYPE_EXIT) {
notify(player, "That is an exit.");
return;
}
if (thing == room) {
notify(player, "You may not link something to itself.");
return;
}
/* abode */
if (!controls(player, room) && !Abode(room)) {
notify(player, "Permission denied.");
break;
}
if (!controls(player, thing)) {
notify(player, "Permission denied.");
} else if (room == HOME) {
notify(player, "Can't set home to home.");
} else {
/* do the link */
db[thing].exits = room; /* home */
notify(player, "Home set.");
}
break;
case TYPE_ROOM:
if ((room = parse_linkable_room(player, room_name)) == NOTHING)
return;
if ((room != HOME) && (Typeof(room) != TYPE_ROOM)) {
notify(player, "That is not a room!");
return;
}
if (!controls(player, thing)) {
notify(player, "Permission denied.");
} else {
/* do the link, in location */
Location(thing) = room; /* dropto */
notify(player, "Dropto set.");
}
break;
default:
notify(player, "Internal error: weird object type.");
fprintf(stderr, "PANIC weird object: Typeof(%d) = %d\n",
thing, Typeof(thing));
break;
}
}
}
/* use this to create a room */
dbref do_dig(player, name, argv, tport)
dbref player;
const char *name;
char *argv[];
int tport; /* @tel player to new location? */
{
dbref room;
#ifdef RESTRICTED_BUILDING
if (!Builder(player)) {
notify(player, "That command is restricted to authorized builders.");
return NOTHING;
}
#endif /* RESTRICTED_BUILDING */
#ifdef GUEST_RESTRICT
if (Guest(player)) {
notify(player, "Guests are not allowed to build.");
return NOTHING;
}
#endif
/* we don't need to know player's location! hooray! */
if (*name == '\0') {
notify(player, "Dig what?");
} else if (!ok_name(name)) {
notify(player, "That's a silly name for a room!");
} else if (can_pay_fees(player, ROOM_COST)) {
room = new_object();
/* Initialize everything */
SET(db[room].name, name);
Owner(room) = Owner(player);
Zone(room) = Zone(player);
Flags(room) = TYPE_ROOM;
Flags(room) |= options.room_flags;
Toggles(room) |= options.room_toggles;
notify(player,
tprintf("%s created with room number %d.", name, room));
if (argv[1] && *argv[1]) {
char nbuff[MAX_COMMAND_LEN];
sprintf(nbuff, "%d", room);
do_real_open(player, argv[1], nbuff, NOTHING);
}
if (argv[2] && *argv[2]) {
char nbuff[MAX_COMMAND_LEN];
sprintf(nbuff, "%d", Location(player));
do_real_open(player, argv[2], nbuff, room);
}
if (tport)
safe_tel(player, room); /* if flag, move the player */
return room;
}
return NOTHING;
}
/* use this to create an object */
dbref do_create(player, name, cost)
dbref player;
char *name;
int cost;
{
dbref loc;
dbref thing;
#ifndef FREE_OBJECTS
#ifdef RESTRICTED_BUILDING
if (!Builder(Owner(player))) {
notify(player, "That command is restricted to authorized builders.");
return NOTHING;
}
#endif /* RESTRICTED_BUILDING */
#endif /* FREE_OBJECTS */
#ifdef GUEST_RESTRICT
if (Guest(player)) {
notify(player, "Guests are not allowed to build.");
return NOTHING;
}
#endif
if (*name == '\0') {
notify(player, "Create what?");
return NOTHING;
} else if (!ok_name(name)) {
notify(player, "That's a silly name for a thing!");
return NOTHING;
} else if (cost < OBJECT_COST) {
cost = OBJECT_COST;
}
if (can_pay_fees(player, cost)) {
/* create the object */
thing = new_object();
/* initialize everything */
SET(Name(thing), name);
Location(thing) = player;
Owner(thing) = Owner(player);
Zone(thing) = Zone(player);
s_Pennies(thing, OBJECT_ENDOWMENT(cost));
Flags(thing) = TYPE_THING;
Flags(thing) |= options.thing_flags;
Toggles(thing) |= options.thing_toggles;
/* endow the object */
if(Wizard(player)) {
if(Pennies(thing) > MAX_WIZ_OBJECT_ENDOWMENT)
s_Pennies(thing, MAX_WIZ_OBJECT_ENDOWMENT);
} else
if (Pennies(thing) > MAX_OBJECT_ENDOWMENT)
s_Pennies(thing, MAX_OBJECT_ENDOWMENT);
/* home is here (if we can link to it) or player's home */
if ((loc = Location(player)) != NOTHING &&
(controls(player, loc) ||
IS(loc, TYPE_ROOM, ROOM_ABODE))) {
db[thing].exits = loc; /* home */
} else {
db[thing].exits = db[player].exits; /* home */
}
/* link it in */
PUSH(thing, db[player].contents);
/* and we're done */
notify(player, tprintf("Created: Object #%d.", thing));
return thing;
}
return NOTHING;
}
void do_clone(player, name)
dbref player;
char *name;
{
dbref clone, thing;
#ifdef GUEST_RESTRICT
if (Guest(player)) {
notify(player, "Guests are not allowed to build.");
return;
}
#endif
init_match(player, name, NOTYPE);
match_everything();
thing = noisy_match_result();
if ((thing == NOTHING))
return;
if (!controls(player, thing)) {
notify(player, "Permission denied.");
return;
}
/* don't allow cloning of destructed things */
if (Going(thing)) {
notify(player, "There's nothing left of it to clone!");
return;
}
/* make sure owner can afford it */
switch (Typeof(thing)) {
case TYPE_THING:
#ifdef RESTRICTED_BUILDING
#ifndef FREE_OBJECTS
if (!Builder(player)) {
notify(player, "Command is for builders only.");
return;
}
#endif
#endif
if (can_pay_fees(player, OBJECT_DEPOSIT(Pennies(thing)))) {
clone = new_object();
memcpy(&db[clone], &db[thing], sizeof(struct object));
db[clone].name = NULL;
SET(db[clone].name, Name(thing));
s_Pennies(clone, Pennies(thing));
atr_cpy(clone, thing);
db[clone].key = dup_bool(db[thing].key);
db[clone].enterkey = dup_bool(db[thing].enterkey);
db[clone].usekey = dup_bool(db[thing].usekey);
db[clone].zone = db[thing].zone;
db[clone].parent = db[thing].parent;
db[clone].flags &= ~WIZARD;
#ifdef ROYALTY_FLAG
db[clone].flags &= ~ROYALTY;
#endif
db[clone].powers = 0; /* zap powers */
db[clone].contents = db[clone].location = db[clone].next = NOTHING;
notify(player, tprintf("Cloned: Object #%d.", clone));
moveto(clone, Location(player));
did_it(player, clone, NULL, NULL, NULL, NULL, "ACLONE", NOTHING);
}
break;
case TYPE_EXIT:
#ifdef RESTRICTED_BUILDING
if (!Builder(player)) {
notify(player, "Command is for builders only.");
return;
}
#endif
clone = do_real_open(player, Name(thing),
tprintf("%d", Location(thing)), NOTHING);
if (!clone)
return;
else {
atr_cpy(clone, thing);
db[clone].key = dup_bool(Key(thing));
db[clone].enterkey = dup_bool(Enterkey(thing));
db[clone].usekey = dup_bool(Usekey(thing));
db[clone].zone = Zone(thing);
db[clone].parent = Parent(thing);
Flags(clone) = Flags(thing);
Flags(clone) &= ~WIZARD;
#ifdef ROYALTY_FLAG
Flags(clone) &= ~ROYALTY;
#endif
db[clone].powers = 0; /* zap powers */
notify(player, "Exit cloned.");
}
break;
default:
notify(player, "You can only clone things and exits.");
return;
}
}